/* This file is part of BonQ - A simple HTTP-based messaging server.
 * Copyright (C) 2009 James Cook
 *
 * BonQ is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License, version 2, as published by the
 * Free Software Foundation.
 *
 * BonQ is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License, version 2,
 * for more details.
 *
 * You should have received a copy of the GNU General Public License, version
 * 2, along with BonQ.  If not, see:
 *
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 */
package com.bonkabonka.queue;

import java.lang.reflect.Method;

/**
 * Root-level administrative queue.
 * 
 * @author jamesc
 */
public final class SystemQueue extends StatusQueue
{
    /**
     * Arbitrarily assigned version String.
     */
    public static final String VERSION = "0.2.0";
    
    private transient SystemCommandHandler cmds;

    /**
     * This attaches the SystemCommandHandler to the bucket and sets the
     * version string.
     * 
     * @param bucket QueueBucket to attach the SystemCommandHandler to
     */
    @Override
    public void init(QueueBucket bucket, String name)
    {
        super.init(bucket, name);
        
        cmds = new SystemCommandHandler(bucket);

        super.push("bonq - Version " + VERSION);
    }

    /**
     * This processes all incoming system commands.  Reflection is used to
     * expose the SystemCommandHandler methods through this interface.
     * 
     * @see SystemCommandHandler
     * 
     * @param message String containing the command to execute
     * @return String with the result of the command
     */
    @Override
    public String push(String message)
    {
        String result = null;

        if(message != null && !message.trim().equals(""))
        {
            Class stringClass = message.getClass();

            String[] data = message.split("\\s+");

            Class[] argTypes = new Class[data.length - 1];
            for(int i = 0; i < argTypes.length; i++)
            {
                argTypes[i] = stringClass;
            }

            Object[] args = new Object[data.length - 1];
            for(int i = 0; i < args.length; i++)
            {
                args[i] = data[i + 1];
            }

            try
            {
                Method m = cmds.getClass().getMethod(data[0], argTypes);
                if(m == null)
                {
                    StringBuffer err = new StringBuffer();
                    err.append("no method named '");
                    err.append(data[0]);
                    err.append("' taking ");
                    err.append(data.length - 1);
                    err.append(" strings as arguments");
                    
                    throw new NoSuchMethodException(err.toString());
                }
                
                Object o = m.invoke(cmds, args);
                if(o == null)
                {
                    result = "OK";
                }
                else
                {
                    result = o.toString();
                }
            }
            catch(Throwable t)
            {
                t.printStackTrace();
                result = "ERR: " + t.toString();
            }
        }

        return result;
    }
}
